package com.sqz.mybatisplus.demo.controller;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqz.mybatisplus.demo.model.User;
import com.sqz.mybatisplus.demo.service.IMybatisPlusTestService;
import com.sqz.mybatisplus.demo.util.InstanceUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.Serializable;
import java.util.*;


/**
 * @author sqz
 * @Description: Service CRUD 接口 控制层
 * @date 2020/06/25
 */
@RestController
@RequestMapping(ServiceInterfaceController.PATH)
@Slf4j
public class ServiceInterfaceController {

    /***
     * 控制层信息
     */
    private static final String CONTENT = "Service层接口:";

    /***
     * 访问路径
     */
    public final static String PATH = "/service";

    @Autowired
    private IMybatisPlusTestService mybatisPlusTestService;

    /**
     * Service层的 insert 方法
     */
    @GetMapping("/save")
    public String save() {

        /***
         * 插入一条记录（选择字段，策略插入）
         */
        User user = InstanceUtil.getUser(CONTENT + "save");
        mybatisPlusTestService.save(user);
        log.info("插入一条记录：" + user);

        /***
         * 插入（批量）
         */
        Collection<User> entityList = new ArrayList<>();
        entityList.add(InstanceUtil.getUser(CONTENT + "save1"));
        entityList.add(InstanceUtil.getUser(CONTENT + "save2"));
        entityList.add(InstanceUtil.getUser(CONTENT + "save3"));
        mybatisPlusTestService.saveBatch(entityList);
        entityList.forEach(s -> log.info("批量插入：" + s.toString()));
        return "OK";
    }

    /**
     * Service层的 saveOrUpdate 方法
     */
    @GetMapping("/saveOrUpdate")
    public String saveOrUpdate() {

        /***
         * 根据TableId注解， 没数据时，这边直接插入
         */
        User user = InstanceUtil.getUser(CONTENT + "saveOrUpdate");
        mybatisPlusTestService.saveOrUpdate(user);
        log.info("插入一条记录：" + user);

        /***
         * 根据TableId注解  插入一条新的数据，如果这条数据的id已经存在，就做修改
         * boolean saveOrUpdate(T entity);
         * T	entity	实体对象
         */
        //修改username 列的值
        user.setUsername(CONTENT + "saveOrUpdate1");
        mybatisPlusTestService.saveOrUpdate(user);
        log.info("修改一条记录：" + user);

        /***
         * 根据updateWrapper尝试更新，否继续执行saveOrUpdate(T)方法
         * boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
         * Wrapper<T>	updateWrapper	实体对象封装操作类 UpdateWrapper
         * mybatis-plus-boot-starter 依赖包要3.3.1的
         */
        //创建wrapper条件构造器 ：不会根据id去更新，会更新 'username' 列为 'saveOrUpdate2' 的项
        UpdateWrapper<User> wrapper = new UpdateWrapper();
        wrapper.lambda().eq(User::getUsername, CONTENT + "saveOrUpdate1");

        //将 username 为 saveOrUpdate2 的列更新为该对象，不会根据id去做判断，但该列的id不会做更新
        user = InstanceUtil.getUser(CONTENT + "saveOrUpdate2");
        mybatisPlusTestService.saveOrUpdate(user, wrapper);
        log.info("修改一条记录：" + user);

        /***
         * 批量修改插入
         * boolean saveOrUpdateBatch(Collection<T> entityList);
         * Collection<T>	entityList	实体对象集合
         */

        Collection<User> entityList = new ArrayList<>();
        //修改已存在的数据
        user.setUsername(CONTENT + "saveOrUpdate3");
        entityList.add(user);
        //插入新数据
        entityList.add(InstanceUtil.getUser(CONTENT + "saveOrUpdate4"));
        entityList.add(InstanceUtil.getUser(CONTENT + "saveOrUpdate5"));
        entityList.add(InstanceUtil.getUser(CONTENT + "saveOrUpdate6"));
        mybatisPlusTestService.saveOrUpdateBatch(entityList);
        entityList.forEach(s -> log.info("批量修改或新增记录：" + s.toString()));
        return "OK";
    }


    /**
     * Service层的 remove 方法
     */
    @GetMapping("/remove")
    public String remove() {

        // 先插入（批量）
        Collection<User> entityList = new ArrayList<>();
        User user1 = InstanceUtil.getUser(CONTENT + "remove1");
        User user2 = InstanceUtil.getUser(CONTENT + "remove2");
        User user3 = InstanceUtil.getUser(CONTENT + "remove3");
        User user4 = InstanceUtil.getUser(CONTENT + "remove4");
        User user5 = InstanceUtil.getUser(CONTENT + "remove5");
        entityList.add(user1);
        entityList.add(user2);
        entityList.add(user3);
        entityList.add(user4);
        entityList.add(user5);
        mybatisPlusTestService.saveBatch(entityList);
        entityList.forEach(s -> log.info("批量新增：" + s));

        /***
         *  根据 entity 条件，删除记录
         *  boolean remove(Wrapper<T> queryWrapper);
         *  Wrapper<T>	queryWrapper	实体包装类 QueryWrapper
         */
        //创建条件构造器，根据id 删除项
        QueryWrapper<User> wrapper = new QueryWrapper();
        wrapper.lambda().eq(User::getUsername, user1.getUsername());
        mybatisPlusTestService.remove(wrapper);
        log.info("根据 entity 条件，删除记录:" + user1);

        /***
         * 根据 ID 删除
         * boolean removeById(Serializable id);
         */
        mybatisPlusTestService.removeById(user2.getUserId());
        log.info("根据 ID 删除:" + user2);

        /***
         * 根据 columnMap 条件，删除记录
         * boolean removeByMap(Map<String, Object> columnMap);
         */
        Map<String, Object> columnMap = new HashMap<>(1);
        columnMap.put("username", user3.getUsername());
        mybatisPlusTestService.removeByMap(columnMap);
        log.info("根据 columnMap 条件，删除记录:" + user3);

        /***
         * 删除（根据ID 批量删除）
         * boolean removeByIds(Collection<? extends Serializable> idList);
         */
        Collection<Serializable> idList = new ArrayList<>();
        idList.add(user4.getUserId());
        idList.add(user5.getUserId());
        mybatisPlusTestService.removeByIds(idList);
        idList.forEach(s -> log.info("根据ID 批量删除:" + s));
        return "OK";
    }


    /**
     * Service层的 update 方法
     */
    @GetMapping("/update")
    public String update() {
        // 先插入（批量）
        Collection<User> entityList = new ArrayList<>();
        User user1 = InstanceUtil.getUser(CONTENT + "update1");
        User user2 = InstanceUtil.getUser(CONTENT + "update2");
        User user3 = InstanceUtil.getUser(CONTENT + "update3");
        User user4 = InstanceUtil.getUser(CONTENT + "update4");
        User user5 = InstanceUtil.getUser(CONTENT + "update5");
        entityList.add(user1);
        entityList.add(user2);
        entityList.add(user3);
        entityList.add(user4);
        entityList.add(user5);
        mybatisPlusTestService.saveBatch(entityList);
        entityList.forEach(s -> log.info("批量新增：" + s));

        User temp;

        /***
         * 根据 UpdateWrapper 条件，更新记录 需要设置setSql
         * boolean update(Wrapper<T> updateWrapper);
         */
        UpdateWrapper<User> wrapper = new UpdateWrapper();
        //设置条件跟值，setSql为赋值，其他为条件，如果除了setSql外没有其他条件约束，则为全表更新，需要注意！！！
        wrapper.lambda().eq(User::getUserId, user1.getUserId()).setSql("username = 'update1(1)'");
        mybatisPlusTestService.update(wrapper);
        //查询该id修改后的值
        temp = mybatisPlusTestService.getById(user1.getUserId());
        log.info("根据 UpdateWrapper 条件,更新记录 需要设置setSql:" + temp);

        /***
         * 根据 whereEntity 条件，更新记录
         * boolean update(T entity, Wrapper<T> updateWrapper);
         */
        user2.setUsername("update2(1)");
        UpdateWrapper<User> wrapper1 = new UpdateWrapper();
        //设置条件
        wrapper.lambda().eq(User::getUserId, user2.getUserId());
        mybatisPlusTestService.update(user2, wrapper1);
        //查询该id修改后的值
        temp = mybatisPlusTestService.getById(user2.getUserId());
        log.info("根据 whereEntity 条件,更新记录:" + temp);

        /***
         * 根据 ID 选择修改
         * boolean updateById(T entity);
         */
        user3.setUsername("update3(1)");
        mybatisPlusTestService.updateById(user3);
        temp = mybatisPlusTestService.getById(user3.getUserId());
        log.info("根据 ID 选择修改:" + temp);

        /***
         * 根据ID 批量更新
         * boolean updateBatchById(Collection<T> entityList);
         */
        mybatisPlusTestService.updateBatchById(entityList);
        entityList.forEach(s -> log.info("批量新增：" + s));

        return "OK";
    }

    /**
     * Service层的 get 方法
     */
    @GetMapping("/get")
    public String get() {
        // 先插入（批量）
        Collection<User> entityList = new ArrayList<>();
        User user1 = InstanceUtil.getUser(CONTENT + "get1");
        User user2 = InstanceUtil.getUser(CONTENT + "get2");
        User user3 = InstanceUtil.getUser(CONTENT + "get3");
        User user4 = InstanceUtil.getUser(CONTENT + "get4");
        User user5 = InstanceUtil.getUser(CONTENT + "get5");
        entityList.add(user1);
        entityList.add(user2);
        entityList.add(user3);
        entityList.add(user4);
        entityList.add(user5);
        mybatisPlusTestService.saveBatch(entityList);
        entityList.forEach(s -> log.info("批量新增：" + s));

        User temp;

        /***
         * 根据 ID 查询
         * T getById(Serializable id);
         */
        temp = mybatisPlusTestService.getById(user1.getUserId());
        log.info("根据 UpdateWrapper 条件,更新记录 需要设置setSql:" + temp);

        /***
         * 根据 Wrapper，查询一条记录。结果集，如果是多个会抛出异常，随机取一条加上限制条件 wrapper.last("LIMIT 1")
         * T getOne(Wrapper<T> queryWrapper);
         */
        QueryWrapper<User> wrapper = new QueryWrapper();
        wrapper.lambda().eq(User::getUsername, CONTENT + "get1");
        try {
            temp = mybatisPlusTestService.getOne(wrapper);
            log.info("根据 UpdateWrapper 条件,更新记录 需要设置setSql:" + temp);
        } catch (Exception e) {
            log.error(CONTENT + "get1:" + "T getOne(Wrapper<T> queryWrapper);方法存在多条记录");
        }


        return "OK";
    }

    /**
     * Service层的 list 方法
     */
    @GetMapping("/list")
    public String list() {
        // 先插入（批量）
        Collection<User> entityList = new ArrayList<>();
        User user1 = InstanceUtil.getUser(CONTENT + "list");
        User user2 = InstanceUtil.getUser(CONTENT + "list");
        User user3 = InstanceUtil.getUser(CONTENT + "list");
        User user4 = InstanceUtil.getUser(CONTENT + "list");
        User user5 = InstanceUtil.getUser(CONTENT + "list");
        entityList.add(user1);
        entityList.add(user2);
        entityList.add(user3);
        entityList.add(user4);
        entityList.add(user5);
        mybatisPlusTestService.saveBatch(entityList);
        entityList.forEach(s -> log.info("批量新增：" + s));


        List<User> users;
        List<Map<String, Object>> userMap;
        List<Object> userObjs;

        /***
         *  查询列表
         * List<T> list(Wrapper<T> queryWrapper);
         */
        QueryWrapper<User> wrapper = new QueryWrapper();
        //查询条件
        wrapper.lambda().eq(User::getUsername, CONTENT + "list");
        users = mybatisPlusTestService.list(wrapper);
        users.forEach(s -> log.info("条件查询列表:" + s.toString()));

        /***
         * 查询所有
         * List<T> list();
         */
        users = mybatisPlusTestService.list();
        users.forEach(s -> log.info("查询列表:" + s.toString()));


        /***
         * 查询（根据ID 批量查询）
         * Collection<T> listByIds(Collection<? extends Serializable> idList);
         */
        List idList = new ArrayList();
        users.forEach(s -> idList.add(s.getUserId()));
        users = mybatisPlusTestService.listByIds(idList);
        users.forEach(s -> log.info("查询（根据ID 批量查询）:" + s.toString()));


        /***
         * 查询（根据 columnMap 条件）
         * Collection<T> listByMap(Map<String, Object> columnMap);
         */
        Map columnMap = new HashMap();
        columnMap.put("username", CONTENT + "list");
        users = mybatisPlusTestService.listByMap(columnMap);
        users.forEach(s -> log.info("查询（根据 columnMap 条件）:" + s.toString()));

        /***
         * 查询所有列表
         * List<Map<String, Object>> listMaps();
         */
        userMap = mybatisPlusTestService.listMaps();
        userMap.forEach(s -> log.info("查询所有列表:" + s.toString()));

        /***
         * 查询列表
         * List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
         */
        QueryWrapper<User> wrapper1 = new QueryWrapper();
        //查询条件
        wrapper1.lambda().eq(User::getUsername, CONTENT + "list");
        userMap = mybatisPlusTestService.listMaps(wrapper1);
        userMap.forEach(s -> log.info("查询所有列表:" + s.toString()));

        /***
         *查询全部记录
         * List<Object> listObjs();
         */
        userObjs = mybatisPlusTestService.listObjs();
        userObjs.forEach(s -> log.info("查询全部记录:" + s.toString()));

        return "OK";
    }

    /**
     * Service层的 page 方法
     */
    @GetMapping("/page")
    public String page() {

        /***
         * 分页对象
         * 使用分页插件前，需先配置 MybatisPlusConfig 类
         * current 当前页
         * size    每页显示条数
         */
        IPage page = new Page(1, 5);
        IPage temp = new Page();

        // 先插入（批量）
        Collection<User> entityList = new ArrayList<>();
        User user1 = InstanceUtil.getUser(CONTENT + "page1");
        User user2 = InstanceUtil.getUser(CONTENT + "page2");
        User user3 = InstanceUtil.getUser(CONTENT + "page3");
        User user4 = InstanceUtil.getUser(CONTENT + "page4");
        User user5 = InstanceUtil.getUser(CONTENT + "page5");
        entityList.add(user1);
        entityList.add(user2);
        entityList.add(user3);
        entityList.add(user4);
        entityList.add(user5);
        mybatisPlusTestService.saveBatch(entityList);
        entityList.forEach(s -> log.info("批量新增：" + s));


        /***
         * 无条件翻页查询
         * IPage<T> page(IPage<T> page);
         */
        temp = mybatisPlusTestService.page(page);
        log.info("当前页:" + temp.getCurrent());
        log.info("每页显示条数:" + temp.getSize());
        log.info("总条数:" + temp.getTotal());
        log.info("当前分页总页数:" + temp.getPages());
        temp.getRecords().forEach(s -> log.info("无条件翻页查询:" + s.toString()));

        /***
         * 翻页查询
         * IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
         */
        //设置查询条件
        QueryWrapper<User> wrapper = new QueryWrapper();
        //设置按创建时间排序
        wrapper.lambda().orderByDesc(User::getCreateTime);
        temp = mybatisPlusTestService.page(page,wrapper);
        log.info("当前页:" + temp.getCurrent());
        log.info("每页显示条数:" + temp.getSize());
        log.info("总条数:" + temp.getTotal());
        log.info("当前分页总页数:" + temp.getPages());
        temp.getRecords().forEach(s -> log.info("翻页查询:" + s.toString()));


        /***
         * 无条件翻页查询
         * IPage<Map<String, Object>> pageMaps(IPage<T> page);
         */
        temp = mybatisPlusTestService.pageMaps(page);
        log.info("当前页:" + temp.getCurrent());
        log.info("每页显示条数:" + temp.getSize());
        log.info("总条数:" + temp.getTotal());
        log.info("当前分页总页数:" + temp.getPages());
        temp.getRecords().forEach(s -> log.info("无条件翻页查询:" + s.toString()));


        /***
         * 翻页查询
         * IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);
         */
        //设置查询条件
        QueryWrapper<User> wrapper1 = new QueryWrapper();
        //设置按创建时间排序
        wrapper1.lambda().orderByDesc(User::getCreateTime);
        temp = mybatisPlusTestService.pageMaps(page,wrapper1);
        log.info("当前页:" + temp.getCurrent());
        log.info("每页显示条数:" + temp.getSize());
        log.info("总条数:" + temp.getTotal());
        log.info("当前分页总页数:" + temp.getPages());
        temp.getRecords().forEach(s -> log.info("翻页查询:" + s.toString()));
        return "OK";
    }

    /**
     * Service层的 count 方法
     */
    @GetMapping("/count")
    public String count() {

        /***
         * 查询总记录数
         * int count();
         */
        int count = mybatisPlusTestService.count();
        log.info("查询总记录数:"+count);

        /***
         * 根据 Wrapper 条件，查询总记录数
         * int count(Wrapper<T> queryWrapper);
         */
        //设置查询条件
        QueryWrapper<User> wrapper = new QueryWrapper();
        //设置按创建时间排序
        wrapper.lambda().eq(User::getMobile,"13000000000");
        int count1 = mybatisPlusTestService.count(wrapper);
        log.info("根据 Wrapper 条件，查询总记录数:"+count1);
        return "OK";
    }



}
